from fastapi import APIRouter, Depends, HTTPException, status, Body
from sqlalchemy.orm import Session
from datetime import timedelta
from typing import Optional

from app.database import get_db
from app.db_models.user import User
from app.schemas.user import UserCreate, UserResponse, Token, UserLogin
from app.schemas.response import Response, ResponseCode
from app.api.auth import (
    verify_password,
    get_password_hash,
    create_access_token,
    ACCESS_TOKEN_EXPIRE_MINUTES
)

router = APIRouter(
    prefix="/user",
    tags=["user"],
    responses={404: {"description": "Not found"}},
)


@router.post("/register", response_model=Response[UserResponse])
def register(user: UserCreate, db: Session = Depends(get_db)):
    """用户注册
    
    创建新用户并保存到数据库
    
    Args:
        user: 用户注册信息，通过请求体获取
        db: 数据库会话，通过依赖注入获取
        
    Returns:
        Response[UserResponse]: 统一响应格式的用户信息
    """
    try:
        # 检查用户名是否已存在
        db_user = db.query(User).filter(User.username == user.username).first()
        if db_user:
            return Response.fail(
                message="用户名已被注册"
            )
        
        # 检查邮箱是否已存在
        db_email = db.query(User).filter(User.email == user.email).first()
        if db_email:
            return Response.fail(
                message="邮箱已被注册"
            )
        
        # 检查密码是否匹配
        if user.confirmPassword and user.password != user.confirmPassword:
            return Response.fail(
                message="两次输入的密码不匹配"
            )
        
        # 创建新用户
        hashed_password = get_password_hash(user.password)
        db_user = User(
            username=user.username,
            email=user.email,
            password=hashed_password
        )
        
        # 保存用户到数据库
        db.add(db_user)
        db.commit()
        db.refresh(db_user)
        
        return Response.success(
            data=db_user,
            message="注册成功"
        )
    except Exception as e:
        # 捕获所有异常并返回错误响应
        db.rollback()  # 回滚事务
        return Response.error(message=f"注册失败: {str(e)}")


@router.post("/login", response_model=Response[Token])
def login(user: UserLogin, db: Session = Depends(get_db)):
    """用户登录
    
    验证用户身份并生成JWT令牌
    支持使用用户名或电子邮箱登录
    
    Args:
        user: 登录信息，通过请求体获取
        db: 数据库会话，通过依赖注入获取
        
    Returns:
        Response[Token]: 统一响应格式的令牌信息
    """
    try:
        # 验证用户 - 分别处理用户名和邮箱登录
        db_user = None
        
        if user.email:
            # 使用邮箱登录
            db_user = db.query(User).filter(User.email == user.email).first()
            if not db_user:
                return Response.fail(
                    code=ResponseCode.UNAUTHORIZED,
                    message="邮箱或密码错误"
                )
        elif user.username:
            # 使用用户名登录
            db_user = db.query(User).filter(User.username == user.username).first()
            if not db_user:
                return Response.fail(
                    code=ResponseCode.UNAUTHORIZED,
                    message="用户名或密码错误"
                )
        
        # 验证密码
        if not verify_password(user.password, db_user.password):
            message = "邮箱或密码错误" if user.email else "用户名或密码错误"
            return Response.fail(
                code=ResponseCode.UNAUTHORIZED,
                message=message
            )
        
        # 创建访问令牌
        access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            data={"sub": db_user.username},  # "sub"是JWT标准声明，表示主题（通常是用户ID或用户名）
            expires_delta=access_token_expires
        )
        
        return Response.success(
            data={"access_token": access_token, "token_type": "bearer"},
            message="登录成功"
        )
    except Exception as e:
        # 捕获所有异常并返回错误响应
        return Response.error(message=f"登录失败: {str(e)}")